/**
 * Generali Solutions d'assurances - Tous droits réservés &copy; 2007 - 2010
 */
package fr.generali.accueilclient.resume.contrat.builder;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import fr.generali.accueilclient.client.om.IAdresse;
import fr.generali.accueilclient.client.om.ICoordonneeBancaire;
import fr.generali.accueilclient.client.om.impl.Adresse;
import fr.generali.accueilclient.client.om.impl.CoordonneeBancaire;
import fr.generali.accueilclient.resume.contrat.om.IResumeContrat;
import fr.generali.accueilclient.resume.contrat.om.IRole;
import fr.generali.accueilclient.resume.contrat.om.impl.ResumeContrat;
import fr.generali.accueilclient.resume.contrat.om.impl.Role;
import fr.generali.accueilclient.utils.constantes.CategorieEnum;
import fr.generali.accueilclient.utils.constantes.CodeRoleEnum;
import fr.generali.accueilclient.utils.stringbuilder.StringBuilderUtils;

import fr.generali.refservcommuns.rce.resume.dto.ctr.avenantscontrat.DTOAvenantContrat;
import fr.generali.refservcommuns.rce.resume.dto.ctr.elementscontrat.DTOModalitesPaiementCotisations;
import fr.generali.refservcommuns.rce.resume.dto.ctr.gestionprimes.DTOPrimeContrat;
import fr.generali.refservcommuns.rce.resume.dto.pty.referencebancaire.DTOCompteBancaireResume;

import fr.generali.refservcommuns.clients.resume.dto.v4.ctr.structurecontrat.DTOContrat;
import fr.generali.refservcommuns.clients.resume.dto.v4.ctr.structurecontrat.DTOProfilSujetAssure;

import fr.generali.refservcommuns.clients.resume.dto.v4.pty.personnes.DTOPersonneResume;
import fr.generali.refservcommuns.clients.resume.dto.v4.ctc.gestioncontacts.DTOAdresseResume;

/**
 * @author Holmes Kelly
 */
public class DTOContrat2ResumeContratBuilder implements IResumeContratBuilder {

    /**
     * 
     */
    private static final int CODE_IBAN_CLE_FIN = 27;

    /**
     * 
     */
    private static final int CODE_IBAN_CLE_DEB = 25;

    /**
     * 
     */
    private static final int CODE_IBAN_COMPTE_FIN = 25;

    /**
     * 
     */
    private static final int CODE_IBAN_COMPTE_DEB = 14;

    /**
     * 
     */
    private static final int CODE_IBAN_GUICHET_FIN = 14;

    /**
     * 
     */
    private static final int CODE_IBAN_GUICHET_DEB = 9;

    /**
     * 
     */
    private static final int CODE_IBAN_BANQUE_FIN = 9;

    /**
     * 
     */
    private static final int CODE_IBAN_BANQUE_DEB = 4;

    /**
     * 
     */
    private static final int CODE_IBAN_LENGTH = 27;

    /**
     * 
     */
    private IResumeContrat resume;

    /**
     * 
     */
    private DTOContrat contrat;

    /**
     * @param contrat contrat
     */
    public DTOContrat2ResumeContratBuilder(DTOContrat contrat) {
        resume = new ResumeContrat();
        this.contrat = contrat;
    }

    /**
     * {@inheritDoc}
     */
    public void buildAdresse() {

        List<DTOPersonneResume> listeRoles = contrat.getRolePersonne();
        if (CollectionUtils.isNotEmpty(listeRoles)) {

            for (int i = 0; i < listeRoles.size(); i++) {
                DTOPersonneResume leRole = listeRoles.get(i);

                if (leRole.getRole().equals(CodeRoleEnum.ROLE_SOUSCRIPTEUR.getCodeRole())) {
                    fillAdresseSouscripteur(leRole);
                }

            }

        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildCategorie() {

        // Categorie par defaut
        resume.setCategorie(CategorieEnum.VIE.getValue());
    }

    /**
     * {@inheritDoc}
     */
    public void buildCodeCompagnie() {
        resume.setCodeCompagnie(contrat.getSocieteDuGroupe());
    }

    /**
     * {@inheritDoc}
     */
    public void buildCodePortefeuille() {
        resume.setCodePortefeuille(contrat.getCodePortefeuille());
    }

    /**
     * {@inheritDoc}
     */
    public void buildCodeProduit() {
        resume.setCodeProduit(contrat.getCodeProduit());
    }

    /**
     * {@inheritDoc}
     */
    public void buildLibelleProduit() {

    }

    /**
     * {@inheritDoc}
     */
    public void buildCodeStatistique() {

        resume.setCodeStatistique(StringBuilderUtils.createBuilder(contrat.getSocieteDuGroupe(),
                        contrat.getCodeProduit()));
    }

    /**
     * {@inheritDoc}
     */
    public void buildCoordonneesBancaires() {

        List<DTOPrimeContrat> listPrimeContrat = contrat.getPrimeContrat();
        if (listPrimeContrat != null && !listPrimeContrat.isEmpty()) {
            List<ICoordonneeBancaire> listCoordonneeBancaire = new ArrayList<ICoordonneeBancaire>();
            ICoordonneeBancaire coordonneeBancaire = null;
            for (DTOPrimeContrat primeContrat : listPrimeContrat) {
                DTOModalitesPaiementCotisations caracteristiquesCotisationSouscrites =
                                primeContrat.getCaracteristiquesCotisationSouscrites();

                if (caracteristiquesCotisationSouscrites != null
                                && caracteristiquesCotisationSouscrites.getReferencesBancairesPaiement() != null) {

                    DTOCompteBancaireResume referencesBancairesPaiement =
                                    caracteristiquesCotisationSouscrites.getReferencesBancairesPaiement();
                    coordonneeBancaire = new CoordonneeBancaire();

                    if (referencesBancairesPaiement.getCodeIBAN() != null
                                    && referencesBancairesPaiement.getCodeIBAN().length() == CODE_IBAN_LENGTH
                                    && StringUtils.isEmpty(referencesBancairesPaiement.getNumeroCompte())) {
                        coordonneeBancaire.setCodeBanque(referencesBancairesPaiement.getCodeIBAN().substring(
                                        CODE_IBAN_BANQUE_DEB, CODE_IBAN_BANQUE_FIN));
                        coordonneeBancaire.setGuichet(referencesBancairesPaiement.getCodeIBAN().substring(
                                        CODE_IBAN_GUICHET_DEB, CODE_IBAN_GUICHET_FIN));
                        coordonneeBancaire.setCompte(referencesBancairesPaiement.getCodeIBAN().substring(
                                        CODE_IBAN_COMPTE_DEB, CODE_IBAN_COMPTE_FIN));
                        coordonneeBancaire.setCle(referencesBancairesPaiement.getCodeIBAN().substring(
                                        CODE_IBAN_CLE_DEB, CODE_IBAN_CLE_FIN));
                        coordonneeBancaire.setIbanComplet(referencesBancairesPaiement.getCodeIBAN());
                    } else {
                        coordonneeBancaire.setCodeBanque(referencesBancairesPaiement.getCodeEtablissement());
                        coordonneeBancaire.setGuichet(referencesBancairesPaiement.getCodeAgence());
                        coordonneeBancaire.setCompte(referencesBancairesPaiement.getNumeroCompte());
                        coordonneeBancaire.setCle(referencesBancairesPaiement.getCleRIB());
                        coordonneeBancaire.setIbanComplet(referencesBancairesPaiement.getCodeEtablissement()
                                        + referencesBancairesPaiement.getCodeAgence()
                                        + referencesBancairesPaiement.getNumeroCompte()
                                        + referencesBancairesPaiement.getCleRIB());
                    }

                    coordonneeBancaire.setNumOrdre(referencesBancairesPaiement.getIdentifiant());

                    if (StringUtils.isNotEmpty(coordonneeBancaire.getNumOrdre())
                                    && StringUtils.isNotEmpty(coordonneeBancaire.getCompte())) {
                        listCoordonneeBancaire.add(coordonneeBancaire);
                    }
                }
            }

            resume.setCoordonneesBancaires(listCoordonneeBancaire);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildDateEffet() {

        DTOAvenantContrat dernierAvenant = contrat.getDernierAvenant();

        if (dernierAvenant != null && dernierAvenant.getPeriodeValidite() != null
                        && dernierAvenant.getPeriodeValidite().getStartDate() != null) {

            Date laDate = dernierAvenant.getPeriodeValidite().getStartDate().toGregorianCalendar().getTime();

            resume.setDateEffet(laDate);
        }

        else if (contrat.getPeriodeValidite() != null && contrat.getPeriodeValidite().getStartDate() != null) {
            Date laDate = contrat.getPeriodeValidite().getStartDate().toGregorianCalendar().getTime();
            resume.setDateEffet(laDate);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildDateEffetNouvelleAffaire() {

        if (contrat.getPeriodeValidite() != null && contrat.getPeriodeValidite().getStartDate() != null) {
            Date laDate = contrat.getPeriodeValidite().getStartDate().toGregorianCalendar().getTime();

            resume.setDateEffetNouvelleAffaire(laDate);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildDateResiliation() {
        if (contrat.getPeriodeValidite() != null && contrat.getPeriodeValidite().getEndDate() != null) {
            resume.setDateResiliation(contrat.getPeriodeValidite().getEndDate().toGregorianCalendar().getTime());
        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildEcheance() {
        if (contrat.getPrimeContrat() != null && !contrat.getPrimeContrat().isEmpty()) {

            DTOPrimeContrat primeContrat = contrat.getPrimeContrat().iterator().next();
            DTOModalitesPaiementCotisations caracteristiquesCotisationSouscrites =
                            primeContrat.getCaracteristiquesCotisationSouscrites();
            String periodicite =
                            caracteristiquesCotisationSouscrites == null ? StringUtils.EMPTY
                                            : caracteristiquesCotisationSouscrites.getPeriodicite();

            resume.setEcheance(periodicite);

        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildFrequence() {
        if (contrat.getPrimeContrat() != null && !contrat.getPrimeContrat().isEmpty()) {

            DTOPrimeContrat primeContrat = contrat.getPrimeContrat().iterator().next();

            resume.setFrequence(primeContrat.getFrequence());

        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildModePaiement() {
        if (contrat.getPrimeContrat() != null && !contrat.getPrimeContrat().isEmpty()) {

            DTOPrimeContrat primeContrat = contrat.getPrimeContrat().iterator().next();
            DTOModalitesPaiementCotisations caracteristiquesCotisationSouscrites =
                            primeContrat.getCaracteristiquesCotisationSouscrites();

            String modePaiement =
                            caracteristiquesCotisationSouscrites == null ? StringUtils.EMPTY
                                            : caracteristiquesCotisationSouscrites.getModePaiement();

            resume.setModePaiement(modePaiement);

        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildMontantAnnuelHT() {
        if (contrat.getPrimeContrat() != null && !contrat.getPrimeContrat().isEmpty()) {

            DTOPrimeContrat primeContrat = contrat.getPrimeContrat().iterator().next();

            resume.setMontantAnnuelHT(primeContrat.getMontantAnnuelHT() == null
                            || primeContrat.getMontantAnnuelHT().getValue() == null ? null : primeContrat
                            .getMontantAnnuelHT().getValue().setScale(2, BigDecimal.ROUND_DOWN));

        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildMontantAnnuelTTC() {
        if (contrat.getPrimeContrat() != null && !contrat.getPrimeContrat().isEmpty()) {

            DTOPrimeContrat primeContrat = contrat.getPrimeContrat().iterator().next();

            resume.setMontantAnnuelTTC(primeContrat.getMontantAnnuelTTC() == null
                            || primeContrat.getMontantAnnuelTTC().getValue() == null ? null : primeContrat
                            .getMontantAnnuelTTC().getValue().setScale(2, BigDecimal.ROUND_DOWN));

        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildMotifFinActivite() {
        if (contrat.getResiliationContrat() != null) {
            resume.setMotifFinActivite(contrat.getResiliationContrat().getMotifFinActivite());
        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildNature() {
        if (contrat.getPrimeContrat() != null && !contrat.getPrimeContrat().isEmpty()) {

            DTOPrimeContrat primeContrat = contrat.getPrimeContrat().iterator().next();

            resume.setNature(primeContrat.getNature());

        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildNatureAvenant() {
        if (contrat.getDernierAvenant() != null) {
            resume.setNatureAvenant(contrat.getDernierAvenant().getNatureAvenant());
        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildNumeroContrat() {
        resume.setNumeroContrat(contrat.getIdentifiant());
    }

    /**
     * {@inheritDoc}
     */
    public void buildNumeroSuspens() {

    }

    /**
     * {@inheritDoc}
     */
    public void buildRoles() {

        List<DTOPersonneResume> listeRoles = contrat.getRolePersonne();
        if (CollectionUtils.isNotEmpty(listeRoles)) {
            List<IRole> roles = new ArrayList<IRole>(listeRoles.size());
            for (int i = 0; i < listeRoles.size(); i++) {
                DTOPersonneResume leRole = listeRoles.get(i);
                IRole role = new Role();
                role.setRole(leRole.getRole());
                role.setNumeroClient(leRole.getIdentifiantRCE());

                if (leRole.getDTOPersonnePhysique() != null) {
                    role.setNom(leRole.getDTOPersonnePhysique().getNom());
                    role.setPrenom(leRole.getDTOPersonnePhysique().getPrenom());
                } else {
                    if (leRole.getDTOPersonneMorale() != null) {
                        role.setNom(leRole.getDTOPersonneMorale().getRaisonSociale());
                        role.setPrenom(null);
                    }
                }

                roles.add(role);
            }
            resume.setRoles(roles);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildStatut() {
        resume.setStatut(contrat.getStatut());
    }

    /**
     * {@inheritDoc}
     */
    public void buildNatureRecouvrement() {
        resume.setNatureRecouvrement(contrat.getNatureRecouvrement());
    }

    /**
     * {@inheritDoc}
     */
    public void buildCoSouscripteur() {
        resume.setCoSouscripteur(contrat.getCoSouscripteur());
    }

    /**
     * {@inheritDoc}
     */
    public void buildPrecision() {
        List<DTOProfilSujetAssure> listProfilSujetAssure = contrat.getProfilSujetAssure();
        if (listProfilSujetAssure != null && !listProfilSujetAssure.isEmpty()) {
            DTOProfilSujetAssure dtoProfilSujetAssure = listProfilSujetAssure.iterator().next();
            resume.setPrecision(dtoProfilSujetAssure == null ? null : dtoProfilSujetAssure.getPrecisionContrat());
        }
    }

    /**
     * {@inheritDoc}
     */
    public void buildModeGestion() {
        resume.setModeGestion(contrat.getModeGestion());
    }

    /**
     * {@inheritDoc}
     */
    public void buildSystemOrigine() {

        resume.setSystemOrigine(contrat.getSystemeOrigine());
    }

    /**
     * {@inheritDoc}
     */
    public IResumeContrat getResumeContrat() {

        return resume;
    }

    /**
     * @param leRole le role
     */
    private void fillAdresseSouscripteur(DTOPersonneResume leRole) {

        IAdresse adresse = new Adresse();
        List<DTOAdresseResume> listAdresse = leRole.getAdresse();
        if (listAdresse != null && !listAdresse.isEmpty()) {
            DTOAdresseResume dtoAdresseresume = listAdresse.iterator().next();
            adresse.setCodePostal(dtoAdresseresume.getCodePostale());
            adresse.setPointGeographique(dtoAdresseresume.getLigne5());
            adresse.setPointRemise(dtoAdresseresume.getLigne4());
            StringBuilder ville = new StringBuilder(StringUtils.EMPTY);
            if (dtoAdresseresume.getLocalite() != null) {
                ville.append(dtoAdresseresume.getLocalite());
            }
            adresse.setVille(ville.toString());
            // adresse.setNumeroVoie(dtoAdresseresume.getNumeroRue());
            adresse.setVoie(dtoAdresseresume.getNomRue());

            resume.setAdresse(adresse);
        }
    }
}
